
import { ControllerBase } from "@/components";
import { dictionary } from "@/modules";
import { Result } from "antd";
import React from "react";

/** 模块数据 */
export interface IModule {
    /** 创建时，生成的唯一标识 */
    key: string,

    /** 模块id */
    id: string,

    /** 模块名称 */
    title: string,

    /** 图标 */
    icon: string | null,

    /** 标签 */
    tag: string | null,

    /** 组件 */
    component: React.LazyExoticComponent<() => JSX.Element>,

    /** 模块描述 */
    description?: string | null;

    /** 模块是否已废弃 */
    deprecated?: string | null;
}

/** 模块实例数据 */
export class ModuleInfo {

    /** 模块实例id */
    id: string;

    /** 模块id */
    moduleId: string;

    /** 实例 */
    element?: React.FunctionComponentElement<any>;

    /**
     * 模块实例数据
     * @param id 模块实例id
     * @param moduleId 模块id
     */
    constructor(id: string, moduleId: string) {
        this.id = id;
        this.moduleId = moduleId;
        this.element =
            (!this.module?.deprecated && this.module?.component)
                ? React.createElement(this.module.component)
                : <Result
                    status="404"
                    title="404"
                    subTitle={this.module?.deprecated || "抱歉，您访问的页面不存在。"}
                />
    }

    /** 模块数据 */
    private get module() {
        return dictionary.get(this.moduleId)
    }
}

export class ModuleControllerState {

    /** 模块实例字典 */
    moduleMap: Map<string, ModuleInfo> = new Map();
}

/** 模块控制器 */
export class ModuleController extends ControllerBase<ModuleControllerState> {

    static Context = React.createContext<ModuleController>(undefined as any);

    static State = ModuleControllerState;

    constructor() {
        super(new ModuleControllerState());
    }

    /** 创建模块 */
    creacteModule = this.action<{ id: string, moduleId: string }>(async (s, opt) => {

        const { id, moduleId } = opt || {};
        if (!id || !moduleId) return;

        if (s.moduleMap.has(id)) {
            return s.moduleMap.get(id);
        } else {
            const module = new ModuleInfo(id, moduleId);
            s.moduleMap.set(id, module);
            s.moduleMap = new Map(s.moduleMap);
            return module;
        }
    })
}
